﻿using System;
using Microsoft.VisualStudio.Debugger.Interop;
using Red.Scripts.Debugger.Defines;

namespace Red.Scripts.Debugger.Remote
{
    public class Program : IDebugProgram2, IDebugProgramNode2
    {
        #region Private Data

        private readonly Guid _guid = Guid.NewGuid();

        #endregion Private Data

        #region Public Properties

        public UriProcess ParentProcess { get; private set; }

        #endregion Public Properties

        #region C-Tor

        public Program( UriProcess parent )
        {
            ParentProcess = parent;
        }

        #endregion C-Tor

        #region IDebugProgram2

        // Deprecated - Not called by the debugger
        public int Attach( IDebugEventCallback2 pCallback )
        {
            throw new NotImplementedException();
        }

        public int CanDetach()
        {
            return Constants.S_OK;
        }

        public int CauseBreak()
        {
            return Constants.S_OK;
        }

        public int Continue( IDebugThread2 pThread )
        {
            return Constants.S_OK;
        }

        public int Detach()
        {
            return Constants.S_OK;
        }

        public int EnumCodeContexts( IDebugDocumentPosition2 pDocPos, out IEnumDebugCodeContexts2 ppEnum )
        {
            throw new NotImplementedException();
        }

        public int EnumCodePaths( string pszHint, IDebugCodeContext2 pStart, IDebugStackFrame2 pFrame, int fSource, out IEnumCodePaths2 ppEnum, out IDebugCodeContext2 ppSafety )
        {
            throw new NotImplementedException();
        }

        public int EnumModules( out IEnumDebugModules2 ppEnum )
        {
            throw new NotImplementedException();
        }

        public int EnumThreads( out IEnumDebugThreads2 ppEnum )
        {
            throw new NotImplementedException();
        }

        public int Execute()
        {
            throw new NotImplementedException();
        }

        public int GetDebugProperty( out IDebugProperty2 ppProperty )
        {
            throw new NotImplementedException();
        }

        public int GetDisassemblyStream( enum_DISASSEMBLY_STREAM_SCOPE dwScope, IDebugCodeContext2 pCodeContext, out IDebugDisassemblyStream2 ppDisassemblyStream )
        {
            throw new NotImplementedException();
        }

        public int GetENCUpdate( out object ppUpdate )
        {
            throw new NotImplementedException();
        }

        public int GetEngineInfo( out string pbstrEngine, out Guid pguidEngine )
        {
            pbstrEngine = "Red Scripts";
            pguidEngine = Defines.Id.Guid.Engine;

            return Constants.S_OK;
        }

        public int GetMemoryBytes( out IDebugMemoryBytes2 ppMemoryBytes )
        {
            throw new NotImplementedException();
        }

        public int GetName( out string pbstrName )
        {
            pbstrName = null;

            return Constants.S_OK;
        }

        public int GetProcess( out IDebugProcess2 ppProcess )
        {
            ppProcess = ParentProcess;

            return Constants.S_OK;
        }

        public int GetProgramId( out Guid pguidProgramId )
        {
            pguidProgramId = _guid;

            return Constants.S_OK;
        }

        public int Step( IDebugThread2 pThread, enum_STEPKIND sk, enum_STEPUNIT Step )
        {
            throw new NotImplementedException();
        }

        public int Terminate()
        {
            throw new NotImplementedException();
        }

        public int WriteDump( enum_DUMPTYPE DUMPTYPE, string pszDumpUrl )
        {
            throw new NotImplementedException();
        }

        #endregion IDebugProgram2

        #region IDebugProgramNode2

        int IDebugProgramNode2.GetProgramName( out string pbstrProgramName )
        {
            pbstrProgramName = ParentProcess.Title;

            return Constants.S_OK;
        }

        int IDebugProgramNode2.GetHostName( enum_GETHOSTNAME_TYPE dwHostNameType, out string pbstrHostName )
        {
            pbstrHostName = ParentProcess.Filename;

            return Constants.S_OK;
        }

        int IDebugProgramNode2.GetHostPid( AD_PROCESS_ID[] pHostProcessId )
        {
            // Return the process id of the debugged process
            pHostProcessId[ 0 ].ProcessIdType = (uint)enum_AD_PROCESS_ID.AD_PROCESS_ID_SYSTEM;
            pHostProcessId[ 0 ].dwProcessId = (uint)ParentProcess.ProcessId;

            return Constants.S_OK;
        }

        int IDebugProgramNode2.GetHostMachineName_V7( out string pbstrHostMachineName )
        {
            throw new NotImplementedException();
        }

        int IDebugProgramNode2.Attach_V7( IDebugProgram2 pMDMProgram, IDebugEventCallback2 pCallback, uint dwReason )
        {
            throw new NotImplementedException();
        }

        int IDebugProgramNode2.GetEngineInfo( out string pbstrEngine, out Guid pguidEngine )
        {
            pbstrEngine = "Red Scripts";
            pguidEngine = Defines.Id.Guid.Engine;

            return Constants.S_OK;
        }

        int IDebugProgramNode2.DetachDebugger_V7()
        {
            throw new NotImplementedException();
        }

        #endregion IDebugProgramNode2
    }
}
